import Qt 4.7
import QtWebKit 1.0
import com.nokia.meego 1.0

import "OAuth.js" as OAuthLogic
import "xRELUrls.js" as Urls

Item {
    id: root

    property string username: ""
    property string password: ""

    property alias pin: pinField.text
    property string token
    property string secret
    property bool externalBrowser: false
    property bool automatedLogin: false

    function beginAuthentication(){
        requestTempToken();
        authenticationStarted();
    }

    signal authenticationStarted
    signal authenticationCompleted (string accessToken, string accessSecret)
    signal authenticationFailed (string errorMsg)

    onAuthenticationStarted: root.state = "AUTOMATED_LOGIN"
    onAuthenticationCompleted: root.state = ""
    onAuthenticationFailed: root.state = ""

    function requestTempToken(){
        //var xhr = OAuthLogic.createOAuthHeader("POST", Urls.API_REQUEST_TOKEN_URL, [["oauth_callback","oob"]]);
        var xhr = OAuthLogic.createOAuthHeader("POST", Urls.API_REQUEST_TOKEN_URL, [["oauth_callback", externalBrowser ? "oob" : Urls.REDIRECT_URL]]);
        console.log("OAuth | Request temp token...");
        xhr.onreadystatechange = function() {
                    if (xhr.readyState === XMLHttpRequest.DONE) {
                        console.log('OAuth | Request temp token finished.');

                        var responseParameters = OAuthLogic.getParameter(xhr.responseText);
                        if(!responseParameters["oauth_callback_confirmed"]) {
                            authenticationFailed("OAuth | Requesting the temp token failed.");
                            return;
                        }

                        token = responseParameters["oauth_token"];
                        secret = responseParameters["oauth_token_secret"];

                        var authorizationUrl = Urls.API_AUTHORIZATION_URL + "?oauth_token="+token+"&mobile=false";
                        if(externalBrowser) {
                            Qt.openUrlExternally(authorizationUrl);
                            pinRow.opacity = 1.0;
                        }
                        else
                            webItem.url = authorizationUrl;
                    }
                }
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.setRequestHeader("Accept-Language", "en");
        xhr.send();
    }

    function tryToLogin() {
        //Try to login with the given username and password
        webItem.settings.javascriptEnabled = true;
        if(webItem.evaluateJavaScript("document.getElementsByClassName('failedvalidation_msg').length > 0")) {
            console.log("OAuth | Login failed. Automated login aborted.");
            authenticationFailed("Wrong username or password.");
            return;
        }

        console.log("OAuth | Try to login with user '" + username + "'...");
        webItem.evaluateJavaScript("document.getElementsByName('username')[0].value = '" + username + "';");
        webItem.evaluateJavaScript("document.getElementsByName('password')[0].value = '" + password + "';");
        webItem.evaluateJavaScript("document.getElementsByTagName('input')[8].click();");
        webItem.settings.javascriptEnabled = false;
    }

    function tryToAllow() {
        //try to click the allow button
        webItem.settings.javascriptEnabled = true;
        webItem.evaluateJavaScript("document.getElementsByName('authorized')[0].click();");
        webItem.settings.javascriptEnabled = false;
    }

    function requestAccessToken(){
        console.log("OAuth | Request access token...");
        var xhr = OAuthLogic.createOAuthHeader("POST", Urls.API_ACCESS_TOKEN_URL, [["oauth_verifier",pin]], {"token":token,"secret":secret});
        xhr.onreadystatechange = function() {
                    if (xhr.readyState === XMLHttpRequest.DONE) {
                        console.log('OAuth | Request access token finished.');
                        var responseParameters = OAuthLogic.getParameter(xhr.responseText);
                        if(responseParameters["oauth_token"] === undefined) {
                            authenticationFailed("OAuth | Requesting the access token failed.");
                            return;
                        }

                        token =responseParameters["oauth_token"];
                        secret = responseParameters["oauth_token_secret"];
                        console.log("OAuth | Request Access Token - Access Token: "+ token + "\nOAuth | Request Access Token - Access Secret:" + secret +"\n");
                        authenticationCompleted(token, secret);
                    }
                }
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.setRequestHeader("Accept-Language", "en");
        xhr.send();
    }

    Item {
        id: busyIndicator
        anchors.fill: parent
        opacity: 0.0

        BusyIndicator {
            id: autoIndicator
            anchors.centerIn: parent
            running: !externalBrowser
            platformStyle: BusyIndicatorStyle {
                size: "large"
            }
        }

        Label {
            anchors.top: autoIndicator.bottom
            anchors.topMargin: 6
            anchors.horizontalCenter: parent.horizontalCenter
            text: externalBrowser ? qsTr("Waiting for the PIN...") : qsTr("OAuth in progress...")
        }
    }

    Flickable {
        anchors.fill: parent
        opacity: !externalBrowser

        contentHeight: webItem.contentsSize.height
        contentWidth: webItem.contentsSize.width

        WebView {
            id: webItem
            anchors.fill: parent;
            settings.javascriptCanOpenWindows: false
            settings.javascriptEnabled: false
            opacity: !automatedLogin

            onLoadStarted: {
                var url = webItem.url.toString();
                console.log("Load started: " + url);
            }

            onLoadFinished: {
                var url = webItem.url.toString();
                console.log("Load finished: " + url);
                if(url.indexOf(Urls.LOGIN_URL) !== -1) {        //Login site
                    if(automatedLogin && !externalBrowser)
                        tryToLogin();
                }
                else if(url.indexOf(Urls.PIN_URL) !== -1) {     //Authorize site
                    tryToAllow();
                    if(externalBrowser)
                        pinRow.opacity = 1.0;
                }
                else if(url.indexOf(Urls.REDIRECT_URL) !== -1) {//Redirect site
                    var pin = OAuthLogic.getParameter(url)["oauth_verifier"];
                    console.log("OAuth | PIN: " + pin)
                    pinField.text = pin;
                    requestAccessToken();
                }
            }

            onLoadFailed: {
                console.log("Load failed: " + webItem.url);
                authenticationFailed("Loading of url '" + webItem.url + "' failed.");
            }
        }
    }

    Rectangle {
        id: pinRow
        anchors.bottom: parent.bottom
        width: parent.width
        height: pinColumn.height
        opacity: 0.0
        color: "#C0FFFFFF"

        Behavior on opacity { NumberAnimation {} }

        Column {
            id: pinColumn
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.bottom: parent.bottom
            anchors.margins: 6
            height: childrenRect.height + 24
            spacing: 12
            Label {
                id: pinLabel
                anchors.horizontalCenter: parent.horizontalCenter
                text: qsTr("Enter the provided PIN here:")
            }
            TextField {
                id: pinField
                width: 250
                anchors.horizontalCenter: parent.horizontalCenter
            }
            Button {
                id: pinButton
                text: qsTr("Ok")
                anchors.horizontalCenter: parent.horizontalCenter
                onClicked: requestAccessToken();
            }
        }
    }

    states: [
        State {
            name: "AUTOMATED_LOGIN"
            PropertyChanges { target: busyIndicator; opacity: 1.0 }
        }
    ]
}
